.NET 中的 WebSocket 支持

您所在的位置:网站首页 websocket 服务端 .NET 中的 WebSocket 支持

.NET 中的 WebSocket 支持

2023-07-22 09:22| 来源: 网络整理| 查看: 265

.NET 中的 WebSocket 支持 项目 05/09/2023

WebSocket 协议支持客户端与远程主机之间的双向通信。 公开 System.Net.WebSockets.ClientWebSocket 通过打开握手建立 WebSocket 连接的能力,它由 ConnectAsync 方法创建和发送。

HTTP/1.1 和 HTTP/2 WebSocket 的差异

基于 HTTP/1.1 的 WebSocket 使用单个 TCP 连接,因此它由连接范围的标头管理,有关详细信息,请参阅 RFC 6455。 请考虑以下示例,了解如何通过 HTTP/1.1 建立 WebSocket:

Uri uri = new("ws://corefx-net-http11.azurewebsites.net/WebSocket/EchoWebSocket.ashx"); using ClientWebSocket ws = new(); await ws.ConnectAsync(uri, default); var bytes = new byte[1024]; var result = await ws.ReceiveAsync(bytes, default); string res = Encoding.UTF8.GetString(bytes, 0, result.Count); await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client closed", default);

由于 HTTP/2 的多路复用性质,必须采用不同的方法。 WebSocket 是按流建立的,有关详细信息,请参阅 RFC 8441。 借助 HTTP/2,可以将一个连接用于多个 Web 套接字流和普通 HTTP 流,并将 HTTP/2 对网络的更高效使用扩展到 WebSocket。 有一个特殊重载 ConnectAsync(Uri, HttpMessageInvoker, CancellationToken) ,它接受 HttpMessageInvoker 以允许重用现有共用连接:

using SocketsHttpHandler handler = new(); using ClientWebSocket ws = new(); await ws.ConnectAsync(uri, new HttpMessageInvoker(handler), cancellationToken); 设置 HTTP 版本和策略

默认情况下, ClientWebSocket 使用 HTTP/1.1 发送开放握手并允许降级。 在 .NET 7 中,可通过 HTTP/2 使用 Web 套接字。 可以在调用 ConnectAsync之前更改它:

using SocketsHttpHandler handler = new(); using ClientWebSocket ws = new(); ws.Options.HttpVersion = HttpVersion.Version20; ws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; await ws.ConnectAsync(uri, new HttpMessageInvoker(handler), cancellationToken); 不兼容的选项

ClientWebSocket 具有用户可以在建立连接之前设置的属性 System.Net.WebSockets.ClientWebSocketOptions 。 但是,当提供 时 HttpMessageInvoker ,它也具有这些属性。 为了避免歧义,在这种情况下,应在 上 HttpMessageInvoker设置属性,并且 ClientWebSocketOptions 应具有默认值。 否则,如果 ClientWebSocketOptions 已更改,则 的 ConnectAsync 重载将引发 ArgumentException。

using HttpClientHandler handler = new() { CookieContainer = cookies; UseCookies = cookies != null; ServerCertificateCustomValidationCallback = remoteCertificateValidationCallback; Credentials = useDefaultCredentials ? CredentialCache.DefaultCredentials : credentials; }; if (proxy is null) { handler.UseProxy = false; } else { handler.Proxy = proxy; } if (clientCertificates?.Count > 0) { handler.ClientCertificates.AddRange(clientCertificates); } HttpMessageInvoker invoker = new(handler); using ClientWebSocket cws = new(); await cws.ConnectAsync(uri, invoker, cancellationToken); 压缩

WebSocket 协议支持 RFC 7692 中定义的每条消息化。 它由 System.Net.WebSockets.ClientWebSocketOptions.DangerousDeflateOptions控制。 如果存在,选项在握手阶段将发送到服务器。 如果服务器支持 per-message-deflate 并且接受选项,则会创建实例, ClientWebSocket 并默认为所有消息启用压缩。

using ClientWebSocket ws = new() { Options = { DangerousDeflateOptions = new WebSocketDeflateOptions() { ClientMaxWindowBits = 10, ServerMaxWindowBits = 10 } } };

重要

在使用压缩之前,请注意启用压缩会使应用程序受到 CRIME/BREACH 类型的攻击,有关详细信息,请参阅 CRIME and BREACH。 强烈建议在发送包含机密的数据时关闭压缩,方法是指定此类消息的 DisableCompression 标志。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3